package solitaire.presentation;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DragSourceMotionListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.dnd.InvalidDnDOperationException;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.WindowConstants;

import solitaire.application.TasDeCartes;
import solitaire.controle.CCarte;
import solitaire.controle.CTasDeCartes;
import solitaire.controle.CTasDeCartesColorees;
import solitaire.controle.CUsine;
import solitaire.presentation.PSabot.MyDragGestureListener;
import solitaire.presentation.PSabot.MyDragSourceListener;
import solitaire.presentation.PSabot.MyDragSourceMotionListener;

@SuppressWarnings("serial")
public class PTasDeCartesColorees extends PTasDeCartes{
	
	private CTasDeCartesColorees controller;
	
	private JPanel foregroundPanel;
	
	private DropTarget dropTarget = null ;
	
	private Window draggedCard = null;
	private PCarte selectedCard = null;
	private DragGestureEvent theInitialEvent ;
	
	private DragSource dragSource = null ;
	private MyDragSourceListener myDragSourceListener = null ;
	private MyDragSourceMotionListener myDragSourceMotionListener = null ;
	
	public PTasDeCartesColorees(CTasDeCartesColorees c)
	{
		super(c);
		this.setDX(0);
		this.setDY(0);
		this.controller = c;
		
		this.setSize(new Dimension(PCarte.largeur, PCarte.hauteur));
		this.setPreferredSize(this.getSize());
		
		this.setBorder(BorderFactory.createLineBorder(Color.black));
		
		foregroundPanel = new JPanel();
		foregroundPanel.setSize(this.getWidth(), this.getHeight());
		foregroundPanel.setPreferredSize(foregroundPanel.getSize());
		foregroundPanel.setLocation(0, 0);
		foregroundPanel.setBackground(new Color((float)1.0, (float)0.0, (float)0.0, (float)0.5));
		
		myDragSourceListener = new MyDragSourceListener () ;
		dragSource = new DragSource () ;
		dragSource.createDefaultDragGestureRecognizer (this, DnDConstants.ACTION_MOVE,
				new MyDragGestureListener ()) ;
		myDragSourceMotionListener = new MyDragSourceMotionListener () ;
		dragSource.addDragSourceMotionListener (myDragSourceMotionListener) ;
		
		dropTarget = new DropTarget(this, new MyDropTargetListener()) ;
	}
	
	/* ---------------------------------------------------------------- */
	/*                               DRAG                               */
	/* ---------------------------------------------------------------- */
	
	class MyDragSourceMotionListener implements DragSourceMotionListener {
		public void dragMouseMoved (DragSourceDragEvent event) {
			draggedCard.setLocation (1 + event.getX (), 1 + event.getY ()) ;
		}
	}
	
	protected class MyDragGestureListener implements DragGestureListener {
		public void dragGestureRecognized (DragGestureEvent event) {
			selectedCard = null ;
			try {
				selectedCard = (PCarte)PTasDeCartesColorees.this.getComponentAt (event.getDragOrigin ()) ;
			} catch (Exception e) {
				
			}
			if (selectedCard != null && PTasDeCartesColorees.this.getComponentZOrder(selectedCard) == 0){
				theInitialEvent = event ;
				
				CTasDeCartes ctdc = new CTasDeCartes("draggedTasDeCartes", new CUsine());
				ctdc.empiler(selectedCard.getControle());
				
				try {
					controller.depiler();
				} catch (Exception e) {
				}
				
				dragSource.startDrag(event, DragSource.DefaultMoveDrop, ctdc.getPresentation(), myDragSourceListener);
				
				draggedCard = new Window ((Window)(getRootPane ().getParent ())) ;
				draggedCard.add(ctdc.getPresentation());
				draggedCard.pack () ;
				draggedCard.setVisible (true) ;
				validate () ;
				repaint () ;
			} else {
				
			}
		}
	}
	
	protected class MyDragSourceListener implements DragSourceListener {

		public void dragDropEnd (DragSourceDropEvent event) {
			if (! event.getDropSuccess ()) {
				selectedCard.setLocation(20, 0);
				controller.empiler(selectedCard.getControle());
				PTasDeCartesColorees.this.validate () ;
				PTasDeCartesColorees.this.repaint () ;
			}
			draggedCard.setVisible (false) ;
		}

		public void dragEnter (DragSourceDragEvent event) {
		}

		public void dragExit (DragSourceEvent event) {
		}

		public void dragOver (DragSourceDragEvent event) {
		}

		public void dropActionChanged (DragSourceDragEvent event) {
		}

	}
	
	/* ---------------------------------------------------------------- */
	/*                               DROP                               */
	/* ---------------------------------------------------------------- */
	
	protected class MyDropTargetListener implements DropTargetListener {
        
        public void dragEnter(DropTargetDragEvent event) {
        	try {
	        	Transferable transferable = event.getTransferable () ;
	        	if (transferable.isDataFlavorSupported (new DataFlavor (PTasDeCartes.class, null))) {
	        		PTasDeCartes tas = (PTasDeCartes)transferable.getTransferData(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType)) ;
	        		if(tas.getNbCartes() == 1 && controller.isEmpilable(tas.getController().getBase())) {
			        	foregroundPanel.setBackground(new Color((float)0.0, (float)1.0, (float)0.0, (float)0.3));
			        	PTasDeCartesColorees.this.add(foregroundPanel, 0);
			        	repaint();
					}
					else {
						foregroundPanel.setBackground(new Color((float)1.0, (float)0.0, (float)0.0, (float)0.3));
			        	PTasDeCartesColorees.this.add(foregroundPanel, 0);
			        	repaint();
					}
				}
			} catch (ClassNotFoundException e) {
			} catch (UnsupportedFlavorException e) {
			} catch (IOException e) {
			} catch (Exception e) {
			}
        }
        
        public void dragExit(DropTargetEvent event) {
        	PTasDeCartesColorees.this.remove(foregroundPanel);
        	repaint();
        }
        
        public void dragOver(DropTargetDragEvent event) {
         }
        
        public void drop(DropTargetDropEvent event) {
            try {
                Transferable transferable = event.getTransferable () ;
                if (event.isLocalTransfer ()) {
                	
                	if (transferable.isDataFlavorSupported (new DataFlavor (PTasDeCartes.class, null))) {
                		PTasDeCartes tas = (PTasDeCartes)transferable.getTransferData(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType)) ;
                		if(tas.getNbCartes() == 1 && controller.isEmpilable(tas.getController().getBase())) {
                			event.acceptDrop(DnDConstants.ACTION_MOVE) ;

                			TasDeCartes ctl = tas.getController();
                			
                			CCarte tmpCard = (CCarte) ctl.getSommet();
                			ctl.depiler();
                			
                			controller.empiler(tmpCard);
                			
                			event.getDropTargetContext().dropComplete(true) ;
                			PTasDeCartesColorees.this.remove(foregroundPanel);
                        	repaint();
                		}
                		else {
                			event.rejectDrop();
                			PTasDeCartesColorees.this.remove(foregroundPanel);
                        	repaint();
                		}
                	}
                	else {
                		event.rejectDrop();
                		PTasDeCartesColorees.this.remove(foregroundPanel);
                		repaint();
                	}
                }
                else {
            		event.rejectDrop();
            		PTasDeCartesColorees.this.remove(foregroundPanel);
            		repaint();
            	}
            } catch (java.io.IOException exception) {
                event.rejectDrop() ;
            } catch (UnsupportedFlavorException ufException) {
                event.rejectDrop() ;
            } catch (java.lang.ClassNotFoundException e) {
                event.rejectDrop() ;
            } catch (InvalidDnDOperationException e) {
            	event.rejectDrop() ;
			} catch (Exception e) {
				event.rejectDrop() ;
			}
        }
        
        public void dropActionChanged(DropTargetDragEvent event) {
        }
        
    }
	
	
	public static void main (String args []) {
		JFrame f = new JFrame ("Test PTasDeCarte") ;
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.getContentPane ().setBackground(new Color(143, 143, 195));

		PCarte c1 = new PCarte ("QH", null);
		c1.setFaceVisible(true);

		PCarte c2 = new PCarte("1D", null);
		c2.setFaceVisible(false);
		
		PCarte c3 = new PCarte("1D", null);
		c3.setFaceVisible(true);
		
		PTasDeCartes ptc = new PTasDeCartesColorees(null);
		
		ptc.empiler(c3);
		//ptc.empiler(c2);
		//ptc.empiler(c1);
		ptc.setVisible(true);
		
		f.getContentPane().add(ptc);
		
		f.setVisible (true) ;
		f.pack();
		
	} // main

}
